/*
 * Copyright (c) 2021 柯华栋
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ipc_server.h"

// ON_POST相关 ---------------------------------------------------------------------------------

#if 0
// TODO. 移动到业务层(mcu_service.c)进行处理, 其他相关函数也一样
// 一般组织关系是 module/xxx文件夹下
// xxx_controller.c(控制器，接收外部调用) -> xxx_service.c(业务处理) -> xxx_model.c(数据模型)
static void on_post_version(ipc_map_t* map)
{
	// TEST 打印
	g_print("\n\t\tON_POST\n");
	g_print("client = %s\n", ipc_map_get_client(map));
	g_print("id = %s\n", 	 ipc_map_get_id(map));
	g_print("value = %s\n",  ipc_map_get_string_value(map));
	
	ipc_string_array_t* strs = ipc_map_get_string_array(map, "strs");
	if (strs != NULL) {
		for (int i = 0; i < ipc_string_array_size(strs); i++)
			g_print("strs[%d] = %s\n", i, ipc_string_array_get(strs, i));
	}
}

static void on_post(ipc_map_t* map)
{
	static id_pointer_map_t* id_fn = NULL;
	if (id_fn == NULL) {
		id_fn = id_pointer_map_new();
		id_pointer_map_set(id_fn, "mcu.version", on_post_version);
	}
	
	controller_on_post fn = id_pointer_map_get_on_post(id_fn, map);
	if (fn != NULL) {
		fn(map);
	}	
}

// 如果不想映射函数，也可以映射int, 然后switch, 其他相关函数也类似
#else	
	
#define POST_VERSION 1

static void on_post(ipc_map_t* map)
{
	static id_s64_map_t* id_number = NULL;
	if (id_number == NULL) {
		id_number = id_s64_map_new();
		// 千万别映射0， 因为获取没有映射的id返回值也是0
		id_s64_map_set(id_number, "mcu.version", POST_VERSION);
	}
	
	switch (id_s64_map_get(id_number, module_get_id_by_map(map))) {
		case POST_VERSION: {
			// TEST 打印
			g_print("\n\t\tON_POST\n");
			g_print("client = %s\n", ipc_map_get_client(map));
			g_print("id = %s\n", 	 ipc_map_get_id(map));
			g_print("value = %s\n",  ipc_map_get_string_value(map));
			
			ipc_string_array_t* strs = ipc_map_get_string_array(map, "strs");
			if (strs != NULL) {
				for (int i = 0; i < ipc_string_array_size(strs); i++)
					g_print("strs[%d] = %s\n", i, ipc_string_array_get(strs, i));
			}
			break;
		}
			
		default:
			break;
	}
}

#endif

// ON_SEND相关 ---------------------------------------------------------------------------------

static ipc_map_t* on_send_version(ipc_map_t* map)
{
	// TEST 打印，并返回结果
	g_print("\n\t\tON_SEND\n");
	g_print("client = %s\n", ipc_map_get_client(map));
	g_print("id = %s\n", 	 ipc_map_get_id(map));
	g_print("value = %s\n",  ipc_map_get_string_value(map));
	
	ipc_map_t* ret = ipc_map_new_string("Value Return From MCU Server");
	g_print("RETURN value = %s\n", ipc_map_get_string_value(ret));
	return ret;
}

static ipc_map_t* on_send(ipc_map_t* map)
{
	static id_pointer_map_t* id_pointer_map = NULL;
	if (id_pointer_map == NULL) {
		id_pointer_map = id_pointer_map_new();
		id_pointer_map_set(id_pointer_map, "mcu.version", on_send_version);
	}	
	controller_on_send fn = id_pointer_map_get_on_send(id_pointer_map, map);
	return fn == NULL ? NULL : fn(map);
}


// HANLDE_UPDATE相关 ---------------------------------------------------------------------------------


static void handle_update_version(GDBusConnection* connection, const gchar* id, gint64 observer)
{
	// TEST 打印， 并通过connection发送一些东西给客户端
	g_print("\n\t\tON_ADD_ID\n");
	g_print("on_add_id %s %ld\n", id, observer);
	
	// 通过connection发送一些东西给客户端
	ipc_map_t* map = ipc_map_new_id_observer_string("mcu.version", observer, "The MCU Version");
	
	g_print("\n\t\tUPDATE\n");
	g_print("id = %s\n", 	ipc_map_get_id(map));	
	g_print("value = %s\n", ipc_map_get_string_value(map));
	
	server_update_con(connection, map);
}


static void handle_update(GDBusConnection* connection, const gchar* id, gint64 observer)
{	
	static id_pointer_map_t* id_pointer_map = NULL;
	if (id_pointer_map == NULL) {
		id_pointer_map = id_pointer_map_new();
		id_pointer_map_set(id_pointer_map, "mcu.version", handle_update_version);
	}
	
	controller_handle_update fn = id_pointer_map_get_handle_update(id_pointer_map, id);
	if (fn != NULL) {
		fn(connection, id, observer);
	}
}


// 导出给控制器工厂方法调用 ------------------------------------------------------------------------

module_controller_t* mcu_get_controller() 
{
	static module_controller_t controller = {on_post, on_send, handle_update};
	return &controller;
}


